# _*_coding:utf-8_*_

from ATS.instrumentDriver import InstCom as inst
from ATS.datamanager.DataManager import DataManager
import time

cmtr = "CMTR1"
OK = 0


def LCR_TEST(cmtr, sweep, bias, meas_range, compensation, meas_func, common):
    """
    cmtr: "CMTR1"
    sweep: {"type":0=V/1=F, "scale":0=linear/1=myLog,"value":[start, stop]}
    bias: {"ac_drive":0.03,"freq":1e6,"dc_bias":0}
    meas_range(ohm): 1000
    compensation: {"is_open":1, "is_short":1, "is_load":1}
    meas_func: {"model":"CPGP"/"CSRS"/"LSRS","output_name":["CpMy"/None,"GpMy"/None],\
    "hlimit":[,],"llimit":[,], "output_setting":{"V":"Volt"/None, "F":"Frequency"/None}}
    common: {"delay_time":0,"hold_time":0,"presoak":0,"sweep_pts":2,\
    "speed":0=short/1=medium/2=long}
    """
    # start_t = time.clock()
    cmtr_obj = None
    output_result = {}
    if __aborttest(cmtr_obj):
        return OK
    cmtr_obj = inst.getinstobj(cmtr)
    result = []
    p_f = []
    if __aborttest(cmtr_obj):
        return OK
    setup(cmtr_obj, meas_range, compensation, common)
    if __aborttest(cmtr_obj):
        return OK
    # return
    bias_src = setbias(cmtr_obj, sweep, bias, common)
    if __aborttest(cmtr_obj):
        return OK
    # return
    cmtr_obj.setmeasmodel(meas_func["model"])
    if __aborttest(cmtr_obj):
        return OK
    # turn on
    cmtr_obj.outputenable(1)
    if __aborttest(cmtr_obj):
        return OK
    if not sweep:  # spot meas
        delay_time = common["delay_time"] + common["hold_time"]
        time.sleep(delay_time)
        for k in meas_func.get("output_setting", {}):
            name = meas_func["output_setting"].get(k)
            if name:
                output_result[name] = [bias_src[k]]
                # __postdata(name,[bias_src[k]])
        result.append(cmtr_obj.measure())
    else:
        if common["sweep_pts"] > 1:
            step = (sweep["value"][1] - sweep["value"][0]) / (common["sweep_pts"] - 1)
        else:
            step = 0
        for i in range(common["sweep_pts"]):
            val = sweep["value"][0] + i * step
            delay_time = common["delay_time"]
            if i == 0:
                delay_time += common["hold_time"]
            if __aborttest(cmtr_obj):
                break
            rval = srcmeas(cmtr_obj, val, delay_time, sweep["type"])
            result.append(rval[0])
            # print "rval",rval
            # print
            for k in meas_func.get("output_setting", {}):
                name = meas_func["output_setting"].get(k)
                if name:
                    if name not in output_result:
                        output_result[name] = []
                    if k in rval[1]:
                        # __postdata(name,[rval[1][k]])
                        output_result[name].append(rval[1][k])
                    else:
                        # __postdata(name,[bias_src[k]])
                        output_result[name].append(bias_src[k])
    # turn off by forceV 0v
    # cmtr_obj.outputoff(const.CMTR_OUTPUT_0V)
    cmtr_obj.setdcbias(0)
    p_f = datahandler(result, meas_func, output_result)
    __postalldata(output_result)
    # elapsed_t = time.clock() - start_t
    # if elapsed_t > 0.15:
    #    print "LCR Test Time:", elapsed_t
    return OK


def datahandler(result, meas_func, output_result):
    is_manual = DataManager().getgdata("Continue_Flag")
    p_f = [1, 1]
    for d in result:
        for index, name in enumerate(meas_func["output_name"]):
            if not name:
                continue
            if name not in output_result:
                output_result[name] = []
            # __postdata(name, d[index])
            output_result[name].append(d[index])
            if meas_func["hlimit"][index] >= d[index] >= meas_func["llimit"][index]:
                p_f[index] = p_f[index] * 1
            else:
                p_f[index] = p_f[index] * 0
    #    for n in output_result:
    #        __postdata(n, output_result[n])
    test_k = []
    for index, name in enumerate(meas_func["output_name"]):
        if not name:
            test_k.append(None)
        else:
            if not is_manual:
                #                __postdata(name+"_PorF",[p_f[index]]) # post pass or fail
                output_result[name + "_PorF"] = p_f[index]
                k = meas_func["model"][index * 2]  # L/C/R
                DataManager().addgdata(k + "_PorF", p_f[index])  # add P/F info into gdata
            # print "addgdata in LCR Test",k+"_PorF",p_f[index]
            if meas_func["model"][index * 2] not in test_k:
                test_k.append(meas_func["model"][index * 2])
            Test_Key = test_k
    return p_f


def setup(cmtr_obj, meas_range, compensation, common):
    # No setup for trigger source, internal source is default
    # setup init continue mode
    cmtr_obj.klockenable(1)
    cmtr_obj.setdisplaypage("MEAS")
    cmtr_obj.setautoinit(1)
    cmtr_obj.setcompensation(compensation)
    cmtr_obj.setmeasrange(meas_range)
    cmtr_obj.setspeed(common["speed"])
    # CVFunc.setmeasmodel(cmtr, meas_func["model"])
    return OK


def setbias(cmtr_obj, sweep, bias, common):
    force_type = sweep.get("type", -1)
    bias_setting = {}
    for k in bias:
        val = bias[k]
        if k == "ac_drive":
            cmtr_obj.setacdrive(val)
            bias_setting["ac_drive"] = val
        elif k == "freq":
            if force_type != 1:
                cmtr_obj.setfrequency(val)
                bias_setting["F"] = cmtr_obj.getinstsetting(["frequency"])["frequency"]
        elif k == "dc_bias":
            if force_type != 0:
                cmtr_obj.setdcbias(val)
                bias_setting["V"] = val
    return bias_setting


def srcmeas(cmtr_obj, src_val, delay_time, type):
    real_src = {}
    if type == 0:  # V
        cmtr_obj.setdcbias(src_val)
        real_src["V"] = src_val
    else:
        cmtr_obj.setfrequency(src_val)
        real_src["F"] = cmtr_obj.getinstsetting(["frequency"])["frequency"]
    time.sleep(delay_time)
    result = cmtr_obj.measure()
    return result, real_src


def __aborttest(cmtr_obj):
    """
    return val
        True: abort
    """
    is_abort = DataManager().getgdata("ATS_Stop_Flag")
    if is_abort:
        if cmtr_obj:
            cmtr_obj.reset()
        return True
    return False


def __postalldata(alldata):
    print(alldata)
    DataManager().postAllDataForOneLoop(alldata)


def __postdata(name, mylist):
    # print "**********",name, mylist
    DataManager().postarraydata(name, mylist)


"""
sweep = {"type":0, "scale":0,"value":[1, 2]}
bias={"ac_drive":0.03,"freq":1e6,"dc_bias":0}
meas_range= 1000
compensation= {"is_open":1, "is_short":1, "is_load":1}
meas_func = {"model":"CPGP","output_name":["CpMy","GpMy"],"hlimit":[None,None],\
             "llimit":[None,None], "output_setting":{"V":"Volt", "F":"Frequency"}}
common= {"delay_time":0,"hold_time":0,"presoak":0,"sweep_pts":2,\
         "speed":0}
LCR_TEST(cmtr,sweep,bias,meas_range,compensation,meas_func,common )
"""
